package pri.damai.xiaowu.auth.security.filter;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import pri.damai.xiaowu.auth.security.authorization.RuiRuanAuthenticationToken;
import pri.damai.xiaowu.auth.security.model.LoginData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * 认证入口
 * @Desc
 * @Author DaMai
 * @Date 2021/10/13 17:47
 * 但行好事，莫问前程。
 */
@Slf4j
public class RuiRuanAuthenticationProcessingFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        log.debug("进入认证入口。");

        if (!Objects.equals(request.getMethod(), HttpMethod.POST.name())) {
            throw new AuthenticationServiceException(
                    "不支持的请求方法: " + request.getMethod());
        }

        if (!Objects.equals(request.getContentType(), MediaType.APPLICATION_JSON_VALUE) && !Objects.equals(request.getContentType(),MediaType.APPLICATION_JSON_UTF8_VALUE)) {
            throw new AuthenticationServiceException(
                    "不支持的 Http content-type:" + request.getContentType());
        }

        LoginData loginData = new LoginData();
        ObjectMapper objectMapper = new ObjectMapper();
        // 未知字段不报错
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            loginData = objectMapper.readValue(request.getInputStream(), LoginData.class);
        } catch (IOException e) {
            log.error("获取登录参数失败。",e);
            throw new AuthenticationServiceException("获取登录参数失败。"+e.getMessage());
        }

        String username = loginData.getUsername();
        String password = loginData.getPassword();
        username = username == null ? "" : username;
        password = password == null ? "" : password;
        username = username.trim();

        RuiRuanAuthenticationToken fastAuthenticationToken = new RuiRuanAuthenticationToken(username, password);
        fastAuthenticationToken.setLoginData(loginData);

        return this.getAuthenticationManager().authenticate(fastAuthenticationToken);
    }
}
